import axios from 'axios';
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { handleError, reportError, type ApiError } from './error-handler';

// 使用全局静态message，避免context依赖
let messageInstance: { [key: string]: (content: string) => void } | null = null;

export const setMessageInstance = (instance: { [key: string]: (content: string) => void }) => {
  messageInstance = instance;
};



class Request {
  private instance: AxiosInstance;

  constructor(config: AxiosRequestConfig) {
    this.instance = axios.create(config);
    this.setupInterceptors();
  }

  private setupInterceptors() {
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config) => {
        let token = null;

        // 尝试从多个地方获取 token
        // 1. 从 Zustand persist 存储 (auth-storage)
        const authStorage = localStorage.getItem('auth-storage');
        if (authStorage) {
          try {
            const authData = JSON.parse(authStorage);
            token = authData.state?.token || authData.token;
          } catch (e) {
            console.debug('Failed to parse auth-storage:', e);
          }
        }

        // 2. 从旧的 token 存储（兼容性）
        if (!token) {
          token = localStorage.getItem('token');
        }

        // 3. 从 auth-token 存储（兼容性）
        if (!token) {
          token = localStorage.getItem('auth-token');
        }

        const url = config.url;

        // 不需要 token 的接口列表
        const noTokenUrls = [
          '/auth/login',
          '/auth/register',
          '/auth/refresh-token'
        ];

        // 如果有 token 且不在免 token 列表中，则添加 Authorization 头
        if (token && url && !noTokenUrls.some(noTokenUrl => url.includes(noTokenUrl))) {
          config.headers.Authorization = `Bearer ${token}`;
          console.debug('Adding Authorization header for:', url);
        } else if (token) {
          console.debug('No token added for URL in noTokenUrls:', url);
        } else {
          console.debug('No token available for:', url);
        }

        return config;
      },
      (error) => {
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.instance.interceptors.response.use(
      (response: AxiosResponse<unknown>) => {
        const responseData = response.data;

        // 处理标准响应格式：{code, message, data}
        if (responseData && typeof responseData === 'object' && 'code' in responseData) {
          const responseObj = responseData as { code: number; message?: string; data?: unknown };

          // 成功响应：code = 200 或 0
          if (responseObj.code === 200 || responseObj.code === 0) {
            // 如果有 data 字段，返回 data；否则返回整个响应
            return responseObj.data !== undefined ? responseObj.data : responseData;
          }

          // 错误响应：使用统一的错误处理
          const apiError: ApiError = {
            code: responseObj.code,
            message: responseObj.message || '请求失败',
            details: responseData,
          };
          handleError(apiError);
          reportError(apiError, { request: config, response: responseData });
          return Promise.reject(apiError);
        }

        // 非标准响应格式，直接返回原始数据
        return responseData;
      },
      (error) => {
        const { response, config: requestConfig } = error;

        // 创建标准化的错误对象
        const apiError: ApiError = {
          code: response?.status || 0,
          message: response?.data?.message || error.message || '网络错误',
          details: {
            response: response?.data,
            request: requestConfig,
            status: response?.status,
          },
        };

        // 使用统一的错误处理
        handleError(apiError);

        // 上报错误
        reportError(apiError, {
          request: requestConfig,
          response: response?.data,
        });

        return Promise.reject(apiError);
      }
    );
  }

  get<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.get(url, config);
  }

  post<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.post(url, data, config);
  }

  put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.put(url, data, config);
  }

  delete<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return this.instance.delete(url, config);
  }
}

export const request = new Request({
  baseURL: '/api',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
});

export default request;